#pragma once
#include "ComponentsPrereq.h"
#include "..\source\ext\btOgre\BtOgreGP.h"

/*
A Collider Component is required to add a shape to an existing rigid body. If you do not have a rigid body when adding a ColliderComponent
a static rigid body will be created. 
*/
namespace ne{
class PhysicsWorld;
class ColliderComponent : public Component, public IComponentObserver {
public:
	ColliderComponent();
	virtual ~ColliderComponent();
	
	virtual void Init();
	const btQuaternion GetRotation();
	const btVector3& GetOrigin();
	const btTransform& GetTransform();
	void SetOrigin(const Ogre::Vector3& p_origin);		// Sets the position of the shape in relation to the rigid body origin.
	void SetRotation(const btQuaternion& rot);	// Sets the rotation of the shape in relation to the rigid body.
	void SetTransform(const btTransform& transform);	// Set transform (position and rotation) at once.
	void SetTransform(const btVector3& v, const btQuaternion& q);
	btCollisionShape* GetCollisionShape() const {return m_shape;}
	int GetIndex() const {return m_index;}
	virtual void Shut();
	virtual void Notify(CEvent* msg);
protected:
	void FinalizeCollider();	// Called internally from a derived Shape after m_shape has been created to do the final work
	btCollisionShape* m_shape;
	btCompoundShape* m_compoundShape;
	btRigidBody* m_rigidBody;
	PhysicsWorld* m_physicsWorld;
	int m_index;			// The index value of the compound shape
};

class BoxColliderComponent :  public ColliderComponent {
public:
	BoxColliderComponent() { m_type |= COMPONENT_COLLIDER_BOX; }
	~BoxColliderComponent(){}

	void Create(float x,float y,float z);
	void Create(const Ogre::Vector3& size);
	void Create();
	luabind::object GetAsLua(lua_State* L) {return luabind::object(L,this);}
};

class SphereColliderComponent :  public ColliderComponent {
public:
	SphereColliderComponent() { m_type |= COMPONENT_COLLIDER_SPHERE; }
	~SphereColliderComponent(){}

	void Create(float radius);
	void Create();
	luabind::object GetAsLua(lua_State* L) {return luabind::object(L,this);}
};

class CapsuleColliderComponent : public ColliderComponent{
public:
	CapsuleColliderComponent();
	~CapsuleColliderComponent();
	void Create(float radius, float length);
	void Create();
	luabind::object GetAsLua(lua_State* L) {return luabind::object(L,this);}
};

class StaticMeshColliderComponent : public ColliderComponent{
public:
	StaticMeshColliderComponent();
	~StaticMeshColliderComponent(void);
	void Create();
	void Shut();
	void Notify(CEvent* msg);
	luabind::object GetAsLua(lua_State* L) {return luabind::object(L,this);}
private:
	btTriangleMesh* m_triangleMesh;
};

}